package com.system.boss.monitor.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.system.boss.monitor.service.dto.PidstatIO;
import com.system.core.utils.ProcessExecutor;
import com.system.core.utils.StringTools;

@Service
public class PidstatService {
	
	DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
	@Autowired
	private Environment environment;
	
	private String homedir="/";
	
	/**
	 * 
	 * Report I/O statistics (kernels 2.6.20 and later only). The following values may be displayed:
	 * <ol>
	 * <li>UID: The real user identification number of the task being monitored</li>
	 * <li>USER: The name of the real user owning the task being monitored</li>
	 * <li>PID: The identification number of the task being monitored.</li>
	 * <li>kB_rd/s: Number of kilobytes the task has caused to be read from disk per second.</li>
	 * <li>kB_wr/s: Number of kilobytes the task has caused, or shall cause to be written to disk per second.</li>
	 * <li>kB_ccwr/s: 任务已取消其写入磁盘的千字节数。 当任务截断一些脏页缓存时，可能会发生这种情况。 在这种情况下，已经解决了另一个任务的某些IO将不会发生。</li>
	 * <li>Command: The command name of the task.</li>
	 * </ol> <font size="2" color="blue"></font>
	 * @throws Exception 
	 */
	public List<PidstatIO> reportIO() throws IOException {
		String cmd;
		if(environment.getActiveProfiles()[0].equalsIgnoreCase("dev")) {
			cmd = "Linux 3.10.0-1062.18.1.el7.x86_64 (iZbp1bv278ligrkg2xmsxaZ) 	05/18/2020 	_x86_64_	(8 CPU)\r\n" + 
					"\r\n" + 
					"01:55:12 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command\r\n" + 
					"01:55:12 PM     0         1      0.72     18.78      0.03  /usr/lib/systemd/systemd --switched-root --system --deserialize 22 \r\n" + 
					"01:55:12 PM     0       566      0.00      1.17      0.00  jbd2/vda1-8\r\n" + 
					"01:55:12 PM     0       667      0.02      0.43      0.00  /usr/lib/systemd/systemd-journald \r\n" + 
					"01:55:12 PM     0       690      0.01      0.00      0.00  /usr/lib/systemd/systemd-udevd \r\n" + 
					"01:55:12 PM     0       720      0.00      0.01      0.00  /sbin/auditd \r\n" + 
					"01:55:12 PM     0       782      0.01      0.00      0.00  /usr/local/cloudmonitor/CmsGoAgent.linux-amd64 \r\n" + 
					"01:55:12 PM   999       816      0.00      0.00      0.00  /usr/lib/polkit-1/polkitd --no-debug \r\n" + 
					"01:55:12 PM    81       824      0.00      0.00      0.00  /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation \r\n" + 
					"01:55:12 PM   998      1060      0.00      0.00      0.00  /usr/sbin/chronyd \r\n" + 
					"01:55:12 PM    32      1081      0.00      0.00      0.00  /sbin/rpcbind -w \r\n" + 
					"01:55:12 PM     0      1096      0.00      0.00      0.00  /usr/sbin/gssproxy -D \r\n" + 
					"01:55:12 PM     0      1123      0.00      0.00      0.00  /usr/lib/systemd/systemd-logind \r\n" + 
					"01:55:12 PM     0      1142      0.00      0.26      0.00  CmsGoAgent-Worker start \r\n" + 
					"01:55:12 PM     0      1439      0.01      0.00      0.00  /usr/bin/python2 -Es /usr/sbin/tuned -l -P \r\n" + 
					"01:55:12 PM     0      1526      0.03      0.13      0.00  /usr/sbin/sshd -D \r\n" + 
					"01:55:12 PM     0      1528      0.03      0.00      0.00  /usr/sbin/aliyun-service \r\n" + 
					"01:55:12 PM     0      1532      0.01      0.02      0.00  /usr/sbin/rsyslogd -n \r\n" + 
					"01:55:12 PM     0      1537      0.01      0.02      0.00  /usr/sbin/crond -n \r\n" + 
					"01:55:12 PM     0      1538      0.00      0.00      0.00  /usr/sbin/atd -f \r\n" + 
					"01:55:12 PM    29      1539      0.00      0.00      0.00  /usr/sbin/rpc.statd \r\n" + 
					"01:55:12 PM     0      1547      0.00      0.00      0.00  /usr/sbin/automount --systemd-service --dont-check-daemon \r\n" + 
					"01:55:12 PM     0      1552      0.00      0.00      0.00  /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220 \r\n" + 
					"01:55:12 PM     0      1553      0.00      0.00      0.00  /sbin/agetty --noclear tty1 linux \r\n" + 
					"01:55:12 PM     0      1564      0.00      0.00      0.00  /usr/local/aegis/aegis_update/AliYunDunUpdate \r\n" + 
					"01:55:12 PM     0      1627      0.02      0.01      0.01  /usr/local/aegis/aegis_client/aegis_10_79/AliYunDun \r\n" + 
					"01:55:12 PM     0      5207      0.00      0.00      0.00  -bash \r\n" + 
					"01:55:12 PM     0      5386      0.00      0.08      0.00  /usr/libexec/openssh/sftp-server \r\n" + 
					"01:55:12 PM   500      5745      0.00      0.01      0.00  java -server -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -Xms14g -Xmx14g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:LargePag\r\n" + 
					"01:55:12 PM     0     22473      0.00      0.00      0.00  pidstat -d -l ";
		} else {
			cmd = ProcessExecutor.executeOnce("pidstat -d -l",homedir)[1];
		}
		List<PidstatIO> pidstats = new ArrayList<PidstatIO>();
		StringReader stringReader = new StringReader(cmd);
		BufferedReader br = new BufferedReader(stringReader);
		String tmp = null;
		String datestr="";
		int line = 1;
		while((tmp = br.readLine()) != null) {
			if(line == 1) {
				datestr = StringTools.getByRegex(tmp, "(\\d+年\\d+月\\d+日)");
			}
				
			if(line > 3) {
				PidstatIO pidstatIO = new PidstatIO();
				String[] array = tmp.split("\\s+");
				int index = 1;
				if(array[index].equalsIgnoreCase("pm") || array[index].equalsIgnoreCase("am")) {
					index += 1;
				}
				pidstatIO.setUid(Long.parseLong(array[index]));
				pidstatIO.setPid(Long.parseLong(array[index+1]));
				pidstatIO.setRead(Float.parseFloat(array[index+2]));
				pidstatIO.setWrite(Float.parseFloat(array[index+3]));
				pidstatIO.setCcwr(Float.parseFloat(array[index+4]));
				StringBuilder commandStr = new StringBuilder();
				for(int i=6;i<array.length;i++) {
					commandStr.append(array[i]);
					commandStr.append(" ");
				}
				pidstatIO.setCommand(commandStr.toString().trim());
//				pidstatIO.setTime(LocalDateTime.parse(datestr+array[0], timeFormatter));
				pidstats.add(pidstatIO);
			}
			line++;
		}
		
		return pidstats;
	}
	
	public static void main(String[] args) throws Exception {
		PidstatService pidstatService = new PidstatService();
		pidstatService.reportIO();
	}
}
